home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / plugin / gamelib / dpblend_sphere.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-31  |  6.3 KB  |  263 lines

  1. #include "..\..\lib\Fly3D.h"
  2. #include "gamelib.h"
  3.  
  4. void dpblend_sphere::init()
  5. {
  6.     // initialize creating a normal map if one does not exists
  7.     if (normalmap==-1)
  8.     {
  9.         build_normalmap("sphere_normals.tga");
  10.         normalmap=flyengine->get_picture("sphere_normals.tga");
  11.     }
  12. }
  13.  
  14. void dpblend_sphere::build_normalmap(char *file)
  15. {
  16.     // creates a normal map for a dpblend_sphere
  17.     // and saves it as a 32 bits/pixel TGA image
  18.     if (pxlsize==0)
  19.         return;
  20.     
  21.     int i,j;
  22.     float x,y;
  23.     double d;
  24.  
  25.     // create picture
  26.     picture p;
  27.     p.CreatePicture32(pxlsize,pxlsize);
  28.     unsigned char *uc=p.buf[0];
  29.  
  30.     // for each pixel
  31.     for( j=0;j<pxlsize;j++ )
  32.     {
  33.         y=(float)(j-pxlsize/2)/(pxlsize/2);
  34.         for( i=0;i<pxlsize;i++ )
  35.         {
  36.             x=(float)(i-pxlsize/2)/(pxlsize/2);
  37.  
  38.             // if pixel insied dpblend_sphere
  39.             d=sqrt(x*x+y*y);
  40.             if (d<1.0f)
  41.             {
  42.                 // store pixel normal
  43.                 uc[0]=(int)(x*127)+128;
  44.                 uc[1]=(int)(y*127)+128;
  45.                 uc[2]=(int)(cos(d)*127)+128;
  46.                 uc[3]=255;
  47.             }
  48.             else 
  49.                 uc[0]=uc[1]=uc[2]=uc[3]=0;
  50.             uc+=4;
  51.         }
  52.     }
  53.  
  54.     // save TGA image in maps subdir
  55.     char name[256];
  56.     strcpy(name,flyengine->flydatapath);
  57.     strcat(name,"maps\\");
  58.     strcat(name,file);
  59.     p.SaveTGA(name);
  60. }
  61.  
  62. int dpblend_sphere::step(int dt)
  63. {
  64.     // move as subclass particle
  65.     return particle::step(dt);
  66. }
  67.  
  68. int dpblend_sphere::message(vector& p,float rad,int msg,int param,void *data)
  69. {
  70.     // get closest light illuminating object
  71.     if (msg==FLYOBJM_ILLUM || msg==FLYOBJM_DYNILLUM)
  72.     {
  73.         float dist=(pos-p).length();
  74.         if (dist<rad && dist<lightdist) 
  75.         {
  76.             lightpos=p;
  77.             lightcolor=*((vector *)data);
  78.             lightradius=rad;
  79.             lightdist=dist;
  80.         }
  81.     }
  82.  
  83.     return 0;
  84. }
  85.  
  86. void dpblend_sphere::draw()
  87. {
  88.     // draw object as single quad polygon
  89.     // always facing the camera
  90.  
  91.     static vector x,y;
  92.     x=flyengine->cam->X*radius;
  93.     y=flyengine->cam->Y*radius;
  94.  
  95.     // select normal map texture
  96.     tc->use(normalmap);
  97.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
  98.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
  99.     
  100.     // alpha test for removing points not in
  101.     // dpblend_sphere but in the quad polygon
  102.     glEnable(GL_ALPHA_TEST);
  103.     glAlphaFunc(GL_GREATER,0);
  104.  
  105.     // if mode 0 or no register combiner extension
  106.     if (mode==0 || glCombinerParameterfvNV==0)
  107.     {
  108.         // just draw polygon with normal map as texture
  109.         glColor3f(1,1,1);
  110.         
  111.         glBegin(GL_QUADS);
  112.         glTexCoord2f(1,0);
  113.         glVertex3f(pos.x+x.x-y.x, pos.y+x.y-y.y, pos.z+x.z-y.z);
  114.         glTexCoord2f(1,1);
  115.         glVertex3f(pos.x+x.x+y.x, pos.y+x.y+y.y, pos.z+x.z+y.z);
  116.         glTexCoord2f(0,1);
  117.         glVertex3f(pos.x+y.x-x.x, pos.y+y.y-x.y, pos.z+y.z-x.z);
  118.         glTexCoord2f(0,0);
  119.         glVertex3f(pos.x-x.x-y.x, pos.y+-x.y-y.y, pos.z-x.z-y.z);
  120.         glEnd();
  121.     }
  122.     else
  123.     {
  124.         vector dir,color;
  125.  
  126.         // initialize register combiners
  127.         init_combiners();
  128.         glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &ambient.x);
  129.         glEnable(GL_REGISTER_COMBINERS_NV);
  130.  
  131.         // if no lights near
  132.         if (lightdist>1e9)
  133.         {
  134.             // clear color (just ambinet)
  135.             glColor4f(0,0,0,0);
  136.             color.null();
  137.         }
  138.         else
  139.         {
  140.             // compute light direction
  141.             dir=(lightpos-pos)*flyengine->cam->mat_t;
  142.             dir.normalize();
  143.             
  144.             // store light dir in the primary color
  145.             glColor4f(
  146.                 (dir.x+1.0f)*0.5f,
  147.                 (dir.y+1.0f)*0.5f,
  148.                 (dir.z+1.0f)*0.5f,
  149.                 1.0f);
  150.                 
  151.             // set up color based on object diffuse color 
  152.             // and light distance factor
  153.             color=diffuse*lightcolor*(1.0f-lightdist/lightradius);
  154.         }
  155.         glCombinerParameterfvNV(GL_CONSTANT_COLOR1_NV,&color.x);
  156.  
  157.         // draw quad polygon
  158.         glBegin(GL_QUADS);
  159.         glTexCoord2f(1,0);
  160.         glVertex3f(pos.x+x.x-y.x, pos.y+x.y-y.y, pos.z+x.z-y.z);
  161.         glTexCoord2f(1,1);
  162.         glVertex3f(pos.x+x.x+y.x, pos.y+x.y+y.y, pos.z+x.z+y.z);
  163.         glTexCoord2f(0,1);
  164.         glVertex3f(pos.x+y.x-x.x, pos.y+y.y-x.y, pos.z+y.z-x.z);
  165.         glTexCoord2f(0,0);
  166.         glVertex3f(pos.x-x.x-y.x, pos.y+-x.y-y.y, pos.z-x.z-y.z);
  167.         glEnd();
  168.  
  169.         // sets no light
  170.         lightdist=1e10;
  171.         // disable redister combiners
  172.         glDisable(GL_REGISTER_COMBINERS_NV);
  173.     }
  174.  
  175.     // disabe alpha test
  176.     glDisable(GL_ALPHA_TEST);
  177. }
  178.  
  179. void dpblend_sphere::init_combiners()
  180. {
  181.     // sets up one combiner for dot product of L and N,
  182.     // then multiply diffuse and add ambinet
  183.     glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 1);
  184.     
  185.     /* Argb = expand(texture0rgb) = N */
  186.     glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
  187.         GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB);
  188.  
  189.     /* Brgb = expand(primaryrgb) = L */
  190.     glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
  191.         GL_PRIMARY_COLOR_NV, GL_EXPAND_NORMAL_NV, GL_RGB);
  192.     
  193.     /* spare0rgb = Argb dot Brgb*/
  194.     glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB,
  195.         GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
  196.         GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE);
  197.  
  198.     /* A = one */
  199.     glFinalCombinerInputNV(GL_VARIABLE_A_NV,
  200.         GL_ONE, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
  201.     /* B = EF */
  202.     glFinalCombinerInputNV(GL_VARIABLE_B_NV,
  203.         GL_E_TIMES_F_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
  204.     /* C = zero */
  205.     glFinalCombinerInputNV(GL_VARIABLE_C_NV,
  206.         GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
  207.     /* D = C0 = ambient illumination contribution */
  208.     glFinalCombinerInputNV(GL_VARIABLE_D_NV,
  209.         GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
  210.     /* E = C1 = diffuse material characteristic */
  211.     glFinalCombinerInputNV(GL_VARIABLE_E_NV,
  212.         GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
  213.     /* F = spare0rgb = diffuse illumination contribution = L dot N */
  214.     glFinalCombinerInputNV(GL_VARIABLE_F_NV,
  215.         GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
  216.     /* G = one */
  217.     glFinalCombinerInputNV(GL_VARIABLE_G_NV,
  218.         GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
  219. }
  220.  
  221. bsp_object *dpblend_sphere::clone()
  222. {
  223.     dpblend_sphere *tmp=new dpblend_sphere;
  224.     *tmp=*this;
  225.     tmp->source=this;
  226.     return tmp;
  227. }
  228.  
  229. int dpblend_sphere::get_custom_param_desc(int i,param_desc *pd)
  230. {
  231.     if (pd!=0)
  232.     switch(i)
  233.     {
  234.     case 0: 
  235.         pd->type='i';
  236.         pd->data=&mode;
  237.         strcpy(pd->name,"mode");
  238.         break;
  239.     case 1:
  240.         pd->type='i';
  241.         pd->data=&pxlsize;
  242.         strcpy(pd->name,"pxlsize");
  243.         break;
  244.     case 2:
  245.         pd->type='p';
  246.         pd->data=&normalmap;
  247.         strcpy(pd->name,"normalmap");
  248.         break;
  249.     case 3:
  250.         pd->type='c';
  251.         pd->data=&ambient;
  252.         strcpy(pd->name,"ambient");
  253.         break;
  254.     case 4:
  255.         pd->type='c';
  256.         pd->data=&diffuse;
  257.         strcpy(pd->name,"diffuse");
  258.         break;
  259.     }
  260.     return 5;
  261. }
  262.  
  263.